#include <xc.h>
#include "../src/SPI.h"
#include "../src/HT_update.h"
#include "config/pic32mk_mcm_curiosity_pro/peripheral/gpio/plib_gpio.h"
#include <string.h>
#include "config/pic32mk_mcm_curiosity_pro/peripheral/spi/spi_master/plib_spi4_master.h"
#include "Uart5.h"
#include "PanelComm.h"
#include "SPI_FrameWork.h"

// A byte of data 10.8US
// The longest interval between frames is between bytes 27us (Between CMD and LEN, time is reserved for the slave to judge CMD and make processing)
// The timeout between the bytes of the SPI slave to determine the frame is 40us

typedef enum
{
	APP_STATE_INITIALIZE,
    APP_STATE_TRANSFER_COMPLETE_WAIT,    
    APP_STATE_WRITE_DATA,        
    APP_STATE_SEND_READ_DATA_CMD,
    APP_STATE_READ_DATA,
    APP_STATE_VERIFY,
    APP_STATE_ERROR,

} APP_STATES;
/* Commands */
#define APP_CMD_WRITE                       0x02
#define APP_CMD_READ                        0x03

#define APP_RX_BUFFER_SIZE                  256
#define APP_TX_BUFFER_SIZE                  256
#define APP_MEM_ADDR                        0x0010
#define APP_TEST_DATA                       "Test Data from SPI Master"
#define APP_TEST_DATA_SIZE                  12  //strlen(APP_TEST_DATA)

volatile bool time2Transfer = false;

void delay(uint32_t count)
{
    uint32_t i;
        
    for (i = 0; i < count; i++)
    {
        asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
        asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
        asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
        asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");        
    }
}

void TMR2EventHandler(uint32_t status, uintptr_t context)
{
    time2Transfer = true;     //every 100us can set data
}



void Delay(void) // 14.5us @FCY=40MHZ
{
    unsigned int temp;
    for( temp = 0; temp < 70; temp++ )  //  103 @FCY=60MHZ
        ;
}

void Delay_5uS(void)   // @FCY=40MHZ
{
    unsigned int temp;
    for( temp = 0; temp < 26; temp++ )   //35  @FCY=60MHZ
        ;
}

void Write_SPI2 (unsigned int command )   //SPI2 Send data (receive before send, ignore receive)
{    
      /* wait for the data to be sent out. 
         When the data is transmitted from SPIxTXB to SPIxSR, the bit is automatically zeroed by the hardware, 
         and the data is still in transmission, so it will be delayed for a certain time before the data is received.
      */
    unsigned int temp;
    temp = SPI2BUF; /* dummy read of the SPI1BUF register to clear the SPIRBF flag */
    temp = temp;
    SPI2BUF = command; /* write the data out to the SPI peripheral */
    while(SPI2STATbits.SPITBF);
}

void Write_SPI3 (unsigned int command )
{
    unsigned int temp;
    temp = SPI3BUF;
    temp = temp;
    SPI3BUF = command;
    while(SPI3STATbits.SPITBF);
}
void Write_SPI4 (unsigned int command )
{
    unsigned int temp;
    temp = SPI4BUF;
    temp = temp;
    SPI4BUF = command;
    while(SPI4STATbits.SPITBF);
}
void Write_SPI5 (unsigned int command )
{
    unsigned int temp;
    temp = SPI5BUF;
    temp = temp;
    SPI5BUF = command;
    while(SPI5STATbits.SPITBF);
}
void Write_SPI6 (unsigned int command )
{
    unsigned int temp;
    temp = SPI6BUF;
    temp = temp;
    SPI6BUF = command;
    while(SPI6STATbits.SPITBF);
}

uint16_t WriteExchange_SPI2(uint16_t data) 
{
    uint16_t temp;
    Write_SPI2(data);            
    while(!SPI2STATbits.SPIRBF);
    temp = SPI2BUF;
    return temp;
}
uint16_t WriteExchange_SPI3(uint16_t data) 
{
    uint16_t temp;
    Write_SPI3(data);            
    while(!SPI3STATbits.SPIRBF);
    temp = SPI3BUF;
    return temp;
}
uint16_t WriteExchange_SPI4(uint16_t data)
{
    uint16_t temp;
    Write_SPI4(data);            
    while(!SPI4STATbits.SPIRBF);
    temp = SPI4BUF;
    return temp;
}

uint16_t WriteExchange_SPI5(uint16_t data)
{
    uint16_t temp;
    Write_SPI5(data);      
    while(!SPI5STATbits.SPIRBF);
    temp = SPI5BUF;
    return temp;
}
uint16_t WriteExchange_SPI6(uint16_t data)
{
    uint16_t temp;
    Write_SPI6(data);            
    while(!SPI6STATbits.SPIRBF);
    temp = SPI6BUF;
    return temp;
}